package 尚硅谷.juc.test10;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 自旋锁的好处：循环比较获取直到成功为止，没有阻塞的现象，
 * 缺点就是：一直循环，导致CPU消耗
 * 自旋的本质就是：CAS理论+while循环
 */
public class SpinLockDemo {

    //原子引用线程
    AtomicReference<Thread> atomicReference=new AtomicReference<>();

    public static void main(String[] args) throws InterruptedException {
        SpinLockDemo spinLockDemo=new SpinLockDemo();
        /**
         * 启动AA线程，执行myLock方法
         * 主线程休眠1秒钟，为了保证AA线程先执行myLock方法，BB线程后执行myLock方法
         * 启动BB线程，执行myLock方法，
         * --------------------------------------------------------------------
         * AA线程先执行myLock方法，此时修改了atomicReference原子引用
         * 一秒之后BB线程执行了myLock方法，这时候调用compareAndSet方法，会一直自旋
         * 直到AA线程执行myUnlock()方法，又将atomicReference原子引用的值修改为null，BB线程才能跳出while循环继续向下执行
         */
        new Thread(()->{
            try {

                spinLockDemo.myLock();
                Thread.sleep(5000);
                spinLockDemo.myUnlock();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"AA").start();

        Thread.sleep(1000);

        new Thread(()->{
            spinLockDemo.myLock();
            spinLockDemo.myUnlock();
        },"BB").start();
    }
    public void myLock(){
        Thread thread=Thread.currentThread();
        System.out.println(Thread.currentThread().getName()+"invoke myLock..........");
        while (!atomicReference.compareAndSet(null,thread)){
            System.out.println(Thread.currentThread().getName()+"......WHILE");
        }
    }

    public void myUnlock(){
        Thread thread = Thread.currentThread();
        atomicReference.compareAndSet(thread,null);
        System.out.println(Thread.currentThread().getName()+"invoke myUnlock.....");
    }
}
